<!--
 * @Description: 
 * @Author: huxianc
 * @Date: 2021-01-07 09:36:29
 * @LastEditors: huxianc
 * @LastEditTime: 2021-01-07 17:24:11
-->
<template>
  <div class="canvas-container">
    <div id="container"></div>
    <div class="mask"></div>
  </div>
</template>

<script>
import Konva from "konva";

// eslint-disable-next-line no-unused-vars
const colors = {
  0: "white",
  1: "rgba(255,0,0,1)",
  2: "yellow",
  3: "blue",
  4: "green",
  5: "purple",
};
// const linePoints=[]
const lineWidth = 1;

export default {
  name: "HelloWorld",
  data() {
    return {
      stage: null,
      layer: null,
      group: null,
      shape: null,
      line: null,
      linePoints: [],
      // 临时存放的 line
      tempPoints: [],
      setPoints: [],
      ctx: null,
    };
  },
  computed: {
    // number[] => {}[]
    splitArr() {
      const arr = [];
      for (let i = 0; i < this.tempPoints.length; i += 2) {
        arr.push({
          x: ~~this.tempPoints[i],
          y: ~~this.tempPoints[i + 1],
          num: 1,
        });
      }
      return arr;
    },
  },
  mounted() {
    this.initStage();
  },
  methods: {
    initStage() {
      this.stage = new Konva.Stage({
        container: "container",
        width: window.innerWidth,
        height: window.innerHeight,
      });

      this.layer = new Konva.Layer();
      this.stage.add(this.layer);

      this.group = new Konva.Group();
      this.layer.add(this.group);

      const canvas = this.initCanvas();
      const image = new Konva.Image({
        image: canvas,
        x: 0,
        y: 0,
      });
      this.layer.add(image);

      const ctx = canvas.getContext("2d");
      this.ctx = ctx;
      ctx.strokeStyle = "#df4b26";
      ctx.lineJoin = "round";
      ctx.lineWidth = 5;

      this.initShape();
    },

    initCanvas() {
      const canvas = document.createElement("canvas");
      canvas.width = this.stage.width();
      canvas.height = this.stage.height();

      return canvas;
    },
    initShape() {
      this.shape = new Konva.Circle({
        x: this.stage.width() / 2,
        y: this.stage.height() / 2,
        radius: 10,
        fill: "rgba(200,200,200,.5)",
      });

      this.layer.add(this.shape);

      const gap = 100;
      for (let i = 1; i < window.innerWidth / gap; i++) {
        const line = new Konva.Line({
          points: [i * gap, 0, i * gap, window.innerHeight],
          strokeWidth: 1,
          stroke: "#000",
        });
        this.layer.add(line);
      }
      for (let i = 1; i < window.innerHeight / gap; i++) {
        const line = new Konva.Line({
          points: [0, i * gap, window.innerWidth, i * gap],
          strokeWidth: 1,
          stroke: "#000",
        });
        this.layer.add(line);
      }

      this.updateStage();

      this.handleMove(this.shape);
    },
    moveFunc(shape) {
      const x = shape.x();
      const y = shape.y();
      const d = 30;
      const distanceX = (Math.random() >= 0.45 ? 1 : -1) * Math.random() * d;
      const distanceY = (Math.random() >= 0.45 ? 1 : -1) * Math.random() * d;

      const X = ~~(x + distanceX);
      const Y = ~~(y + distanceY);

      const resX = X < 0 || X > this.stage.width() ? this.stage.width() / 2 : X;
      const resY =
        Y < 0 || Y > this.stage.height() ? this.stage.height() / 2 : Y;

      return {
        x: resX,
        y: resY,
      };
    },
    initMoveLine() {
      // this.line&&this.line.destroy()
      this.line = new Konva.Line({
        points: this.linePoints,
        stroke: colors[1],
        strokeWidth: lineWidth,
        tension: 0.7,
        lineCap: "round",
        lineJoin: "round",
      });
      this.layer.add(this.line);
    },
    handleMove(node) {
      this.initMoveLine();
      // let index = 0;
      // const count = 10;
      const time = 1 * 1000;
      let timer = setInterval(() => {
        // if (index >= count) {
        //   clearInterval(timer);
        //   timer = null;
        // }
        // index++;
        // console.log(index);
        const pos = this.moveFunc(this.shape);
        node.to({
          ...pos,
          duration: time / 1000,
          onUpdate: () => {
            const x = node.x();
            const y = node.y();
            this.linePoints = this.linePoints.concat([x, y]);
            this.tempPoints = this.tempPoints.concat([x, y]);
            this.line.points(this.linePoints);
            this.line.moveToBottom();
            this.updateStage();
          },
          onFinish: () => {
            // 去重
            const setArr = this.splitArr.reduce((cur, next, index) => {
              if (index === 0) {
                cur.push(next);
              } else {
                const isIn = cur.some(
                  item => item.x === next.x && item.y === next.y
                );
                if (!isIn) {
                  cur.push(next);
                }
              }

              return cur;
            }, []);

            // setPoints
            if (this.setPoints.length === 0) {
              this.setPoints.push(...setArr);
            } else {
              setArr.forEach(item => {
                // 判断 去重数组中的数据 setPoints 是否拥有
                const index = this.setPoints.findIndex(
                  ele => ele.x === item.x && ele.y === item.y
                );
                // setPoints 存在 当前数据
                if (index > -1) {
                  this.setPoints[index].num = this.setPoints[index].num + 1;
                  if (this.setPoints[index].num > 5) {
                    this.setPoints[index].num = 5;
                  }
                  // init dot
                  const { x, y } = item;
                  const name = `${x}-${y}`;
                  const node = this.stage.findOne("." + name);
                  const color = colors[this.setPoints[index].num];
                  if (node) {
                    node.fill(color);
                    node.moveToTop();
                  } else {
                    const dot = new Konva.Rect({
                      width: 1,
                      height: 1,
                      fill: color,
                      x,
                      y,
                      name,
                    });
                    this.group.add(dot);
                    dot.moveToTop();
                  }
                } else {
                  this.setPoints.push(item);
                }
              });
            }

            const attrsArr = Array.from(this.group.children).map(
              item => item.attrs
            );

            this.tempPoints = [];
            console.log(attrsArr);
          },
        });
        this.updateStage();
      }, time);

      this.$once("hook:beforeDestroy", () => {
        clearInterval(timer);
        timer = null;
      });
    },
    updateStage() {
      this.stage.batchDraw();
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.canvas-container {
  position: relative;
  overflow: hidden;
  /* background-color: antiquewhite; */
}
canvas {
  display: block;
}
.mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
}
</style>
